local zip = require "zip"
local _pigsty = require "industry.pigsty"
local _store = require "industry.store"
local _farm = require "industry.farm"
local _crafting = require "industry.crafting"
local ArchiveKeys = require "Data.ArchivesData"
local Archives = {} ---@type table<RoleID, dumplings>

local pigstyMap = {} ---@type table<RoleID, Pigsty>
local storeMap = {} ---@type table<RoleID, Store>
local farmMap = {} ---@type table<RoleID, Farm>
local craftingMap = {} ---@type table<RoleID, Crafting>

---@export
---@desc 导入存档
---@param _role Role
function ImportArchive(_role)
    local data = ""
    for v = 1008, 1057, 1 do
        data = data .. (_role.get_archive_by_type(Enums.ArchiveType.Str, v) or "")
    end
    if #data > 0 then
        Archives[_role.get_roleid()] = zip.deserialize(data)
    else
        Archives[_role.get_roleid()] = require "dataS"
    end
end

---@export
---@desc 保存存档
---@param _role Role
function SaveArchive(_role)
    local ROLEID = _role.get_roleid()
    storeMap[ROLEID]:save_data()
    pigstyMap[ROLEID]:save_data()
    farmMap[ROLEID]:save_data()
    craftingMap[ROLEID]:save_data()


    local data = zip.serialize(Archives[ROLEID] or require "dataS")
    local data_string = zip.split_into_chunks(data, 50)
    for index = 1008, 1057, 1 do
        if data_string[index - 1007] then
            _role.set_archive_by_type(Enums.ArchiveType.Str, index, data_string[index - 1007])
        end
    end
end

---@export
---@desc 初始化地皮
---@param _role Role
function InitializePlot(_role)
    local ROLEID = _role.get_roleid()
    ---猪圈产业
    local A_pigsty = _pigsty.Pigsty:new(_role)
    A_pigsty:set_metadata(Archives[ROLEID]["猪圈"])
    A_pigsty:set_rootdata(Archives[ROLEID]["门店"])
    A_pigsty:start()
    pigstyMap[ROLEID] = A_pigsty

    ---门店产业
    local A_store = _store.Store:new(_role)
    A_store:set_metadata(Archives[ROLEID]["门店"])
    A_store:start()
    storeMap[ROLEID] = A_store

    ---麦田产业
    local A_farm = _farm.Farm:new(_role)
    A_farm:set_metadata(Archives[ROLEID]["麦田"])
    A_farm:set_rootdata(Archives[ROLEID]["门店"])
    A_farm:start()
    farmMap[ROLEID] = A_farm

    ---锅炉产业
    local A_crafting = _crafting.Crafting:new(_role)
    print(Archives[ROLEID]["锅炉"])
    A_crafting:set_metadata(Archives[ROLEID]["锅炉"])
    A_crafting:set_rootdata(Archives[ROLEID]["门店"])
    craftingMap[ROLEID] = A_crafting
end

---@export
---@desc 收割作物
---@param user Role
---@param _role Role
---@param name string
---@param order integer
function HarvestCrop(user, _role, name, order)
    local RoleID = _role.get_roleid()
    farmMap[RoleID]:harvest(user, name, order)
end

---@export
---@desc 获取指定产业信息
---@param _role Role
---@param _name string
---@return string
function GetIndustrtyInfo(_role, _name)
    local ROLEID = _role.get_roleid()
    if _name == "猪圈产业" then
        return pigstyMap[ROLEID]:get_info()
    elseif _name == "门店产业" then
        return storeMap[ROLEID]:get_info()
    elseif _name == "麦田-芦苇产业" then
        return farmMap[ROLEID]:get_info("芦苇")
    elseif _name == "麦田-水稻产业" then
        return farmMap[ROLEID]:get_info("水稻")
    elseif _name == "麦田-甘蔗产业" then
        return farmMap[ROLEID]:get_info("甘蔗")
    elseif _name == "麦田-枣树产业" then
        return farmMap[ROLEID]:get_info("枣树")
    elseif _name == "锅炉产业" then
        return craftingMap[ROLEID]:get_info()
    end
    return ""
end

---@export
---@desc 获取麦田指定作物信息
---@param _role Role
---@param _name string
---@param order integer
---@return string
function GetSpecInfo(_role, _name, order)
    local ROLEID = _role.get_roleid()
    if _name == "芦苇" then
        return farmMap[ROLEID]:get_spec_info("芦苇", order)
    elseif _name == "水稻" then
        return farmMap[ROLEID]:get_spec_info("水稻", order)
    elseif _name == "甘蔗" then
        return farmMap[ROLEID]:get_spec_info("甘蔗", order)
    elseif _name == "枣树" then
        return farmMap[ROLEID]:get_spec_info("枣树", order)
    end
    return ""
end

---获取指定产业
---@param _role Role
---@param _name string
---@return Store | Pigsty | Farm | nil
local function get_spec_industrty(_role, _name)
    local ROLEID = _role.get_roleid()
    if _name == "猪圈产业" then
        return pigstyMap[ROLEID]
    elseif _name == "门店产业" then
        return storeMap[ROLEID]
    elseif _name == "麦田产业" then
        return farmMap[ROLEID]
    end
    return nil
end

---@export
---@desc 升级指定产业
---@param _role Role
---@param _name string
function UpgradeIndustry(_role, _name)
    local ROLEID = _role.get_roleid()
    local industry
    local spec_name
    if _name == "猪圈产业" then
        industry = pigstyMap[ROLEID]
    elseif _name == "门店产业" then
        industry = storeMap[ROLEID]
    elseif _name == "麦田-芦苇产业" then
        industry = farmMap[ROLEID]
        spec_name = "芦苇"
    elseif _name == "麦田-水稻产业" then
        industry = farmMap[ROLEID]
        spec_name = "水稻"
    elseif _name == "麦田-甘蔗产业" then
        industry = farmMap[ROLEID]
        spec_name = "甘蔗"
    elseif _name == "麦田-枣树产业" then
        industry = farmMap[ROLEID]
        spec_name = "枣树"
    else
        return
    end
    local store = get_spec_industrty(_role, "门店产业") --[[@as Store]]
    local assets = store.assets
    local levelup_money
    if spec_name ~= nil then
        ---@diagnostic disable-next-line: param-type-mismatch
        levelup_money = industry:get_levelup_money(spec_name)
    else
        levelup_money = industry:get_levelup_money()
    end
    if assets >= levelup_money then
        store:deduct_assets(levelup_money)
        if spec_name ~= nil then
            ---@diagnostic disable-next-line: param-type-mismatch
            industry:levelup(spec_name)
        else
            industry:levelup()
        end
    else
        _role.show_tips("金币不够，无法升级", 3.0)
    end
end

---@export
---@desc 获得收益
---@param _role Role
---@param profit integer
function GetProfit(_role, profit)
    storeMap[_role.get_roleid()]:get_profit(profit)
end

---@export
---@desc 叠加增益
---@param _role Role
---@param scale integer
---@param duration integer
function AddBonus(_role, scale, duration)
    storeMap[_role.get_roleid()]:add_bonus(scale, duration)
end

---@export
---@desc 打开合成台
---@param user Role
---@param whose Role
function OpenCraftingTable(user, whose)
    craftingMap[whose.get_roleid()]:open_gui(user)
end

---完成初始化
LuaAPI.global_register_trigger_event({ EVENT.TIMEOUT, 1 }, function()
    for order, player in ipairs(GameAPI.get_all_valid_roles()) do
        player.set_kv_by_type(Enums.ValueType.Int, "编号", order)
        ImportArchive(player)
        InitializePlot(player)
        LuaAPI.global_register_trigger_event({ EVENT.SPEC_ROLE_EXIT_GAME, player }, function()
            local ROLEID = player.get_roleid()
            SaveArchive(player)
            storeMap[ROLEID]:stop()
            pigstyMap[ROLEID]:stop()
            craftingMap[ROLEID]:stop()
            farmMap[ROLEID]:stop()
        end)

        local industryNameList = {
            "猪圈产业", "鸡圈产业",
            "麦田-水稻产业", "麦田-甘蔗产业",
            "麦田-芦苇产业", "麦田-枣树产业",
            "加工台产业", "门店产业", "锅炉产业"
        }
        local rootdata = get_spec_industrty(player, "门店产业") --[[@as Store]]
        for _, industryName in ipairs(industryNameList) do
            local industry = get_spec_industrty(player, industryName) --[[@as Store | Farm | Pigsty]]
            LuaAPI.unit_register_trigger_event(player.get_ctrl_unit(), { EVENT.CUSTOM_EVENT, "尝试升级" .. industryName },
                function()
                    local assets = rootdata.assets
                    local levelup_money = industry:get_levelup_money()
                    if assets >= levelup_money then
                        rootdata:deduct_assets(levelup_money)
                    else
                        GlobalAPI.show_tips(("金币不够！还差%d"):format(levelup_money - assets), 3.0)
                    end
                end
            )
        end
    end
end)
